#include "main.h"
#include "IIC.h"

#define	SDA_PIN		GPIO_PIN_1
#define	SDA_TYPE	GPIOA
#define	SCK_PIN		GPIO_PIN_0
#define	SCK_TYPE	GPIOA


#define IIC_SCK_HIGH()    	HAL_GPIO_WritePin(SCK_TYPE, SCK_PIN, GPIO_PIN_SET)
#define IIC_SCK_LOW() 		HAL_GPIO_WritePin(SCK_TYPE, SCK_PIN, GPIO_PIN_RESET)
#define IIC_SDA_HIGH()    	HAL_GPIO_WritePin(SDA_TYPE, SDA_PIN, GPIO_PIN_SET)
#define IIC_SDA_LOW() 		HAL_GPIO_WritePin(SDA_TYPE, SDA_PIN, GPIO_PIN_RESET)
#define READ_SDA()   		HAL_GPIO_ReadPin(SDA_TYPE, SDA_PIN)

#define	IIC_DELAY()	delay_us(1)

void SDA_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	GPIO_InitStruct.Pin = SDA_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SDA_TYPE, &GPIO_InitStruct);
}

void SDA_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	GPIO_InitStruct.Pin = SDA_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SDA_TYPE, &GPIO_InitStruct);
}

void IIC_InterfaceReset(void)
{
	u8 i;

	SDA_OUT();
	IIC_SCK_HIGH();
	IIC_SDA_HIGH();
	HAL_Delay(10);
	
	for(i=0; i<18; i++)
	{
		IIC_SCK_LOW();
		delay_us(100);
		IIC_SDA_HIGH();
		delay_us(100);
	}
	
	HAL_Delay(10);
	
	IIC_SCK_HIGH();
	IIC_SDA_HIGH();
}



void IIC_Init(void)
{
	 GPIO_InitTypeDef GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin = SDA_PIN | SDA_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	
	HAL_GPIO_WritePin(SDA_TYPE, SDA_PIN, GPIO_PIN_SET);
	HAL_GPIO_WritePin(SCK_TYPE, SCK_PIN, GPIO_PIN_SET);
}

void IIC_DeInit( void )
{
	 GPIO_InitTypeDef GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin = SDA_PIN | SDA_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	 
	HAL_GPIO_WritePin(SDA_TYPE, SDA_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(SCK_TYPE, SCK_PIN, GPIO_PIN_RESET);
	
}


void IIC_Start(void)
{
	SDA_OUT();
	IIC_SDA_HIGH();
	IIC_SCK_HIGH();
	IIC_DELAY();
	IIC_SDA_LOW();
	IIC_DELAY();
	IIC_SCK_LOW();
}

void IIC_Stop(void)
{
	SDA_OUT();
	IIC_SCK_LOW();
	IIC_SDA_LOW();
	IIC_DELAY();
	IIC_SCK_HIGH();
	IIC_DELAY();
	IIC_SDA_HIGH();
	IIC_DELAY();
}

static void IIC_ACK(void)
{
	IIC_SCK_LOW();
	SDA_OUT();
	IIC_SDA_LOW();
	IIC_DELAY();
	IIC_SCK_HIGH();
	IIC_DELAY();
	IIC_SCK_LOW();
}

static void IIC_NoACK(void)
{
	IIC_SCK_LOW();	
	SDA_OUT();
	IIC_SDA_HIGH();
	IIC_DELAY();
	IIC_SCK_HIGH();
	IIC_DELAY();
	IIC_SCK_LOW();
}

unsigned char IIC_WaitACK(void)
{
	unsigned char ucErrTime=0;
	SDA_IN();
	IIC_SDA_HIGH();	
	IIC_DELAY();	
	IIC_SCK_HIGH();
	IIC_DELAY();
	while(READ_SDA())
	{
		ucErrTime++;
		if(ucErrTime >250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCK_LOW();
	return 0;
}

void IIC_WriteByte(unsigned char data)
{
	unsigned char i;
	
	SDA_OUT();
	IIC_SCK_LOW();
	for(i=0; i<8; i++)
	{
		if(data & 0x80)
			IIC_SDA_HIGH();
		else
			IIC_SDA_LOW();
		data <<= 1;
		IIC_DELAY();
		IIC_SCK_HIGH();
		IIC_DELAY();
		IIC_SCK_LOW();
		IIC_DELAY();
	}	
}

unsigned char IIC_ReadByte(unsigned char IsAck)
{
	unsigned char i, Receive = 0;
	
	SDA_IN();
	for(i=0; i<8; i++)
	{
		IIC_SCK_LOW();
		IIC_DELAY();
		IIC_SCK_HIGH();
		IIC_DELAY();
		Receive <<= 1;
		if(READ_SDA())
			Receive++;
		IIC_DELAY();
	}
	if(IsAck)
		IIC_ACK();
	else
		IIC_NoACK();
	
	return Receive;
}	
